package ua.khpi.si.kit49.diploma.service;

import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import ua.khpi.si.kit49.diploma.db.dao.UserDAO;
import ua.khpi.si.kit49.diploma.db.dao.UserRoleDAO;
import ua.khpi.si.kit49.diploma.db.dto.User;
import ua.khpi.si.kit49.diploma.db.dto.UserRole;

/**
 * Implementation of registration service
 * 
 * @author netstalk3r
 * 
 */

@Service("registrationService")
public class RegistrationServiceImpl implements RegistrationService {

	private static final Boolean ENABLE_TRUE = true;

	private static final Logger log = Logger
			.getLogger(RegistrationServiceImpl.class);

	@Autowired(required = true)
	UserDAO userDAO;

	@Autowired(required = true)
	UserRoleDAO userRoleDAO;

	@Autowired(required = true)
	PasswordEncoder passwordEncoder;

	RegistrationServiceImpl() {
		super();
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
	public void registerUser(User user, Boolean isAdmin) {
		log.info("User registration");
		user.setPassword(passwordEncoder.encodePassword(user.getPassword(),
				user.getUsername()));
		user.setEnabled(ENABLE_TRUE);
		saveOrUpdateUser(user);
		user = getUserByUsername(user.getUsername());
		log.debug("User id = " + user.getId());
		UserRole userRole = new UserRole();
		userRole.setUser(user);
		if (isAdmin) {
			userRole.setAuthority(ROLE_ADMIN);
		} else {
			userRole.setAuthority(ROLE_USER);
		}
		userRoleDAO.saveOrUpdateUserRole(userRole);
		log.info("Registration success");
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public User getUserById(Integer id) {
		return userDAO.getUserById(id);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public User getUserByEmail(String email) {
		return userDAO.getUserByEmail(email);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public User getUserByUsername(String username) {
		return userDAO.getUserByUsername(username);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public List<User> getAllUsers() {
		return userDAO.getAllUsers();
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
	public void saveOrUpdateUser(User user) {
		userDAO.saveOrUpdateUser(user);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
	public void removeUsers(List<Integer> usersIds) {
		userDAO.removeUsers(usersIds);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
	public void banUnbanUsers(List<Integer> usersIds, Boolean enabled) {
		userDAO.banUsers(usersIds, enabled);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
	public void updateUser(User user) {
		User updateUser = userDAO.getUserById(user.getId());
		UserRole updateUserRole = updateUser.getUserRole();
		if (!(updateUserRole.getAuthority().equalsIgnoreCase(user.getUserRole()
				.getAuthority()))) {
			updateUser.getUserRole().setAuthority(
					user.getUserRole().getAuthority());
		}
		String verificablePss = passwordEncoder.encodePassword(
				user.getPassword(), user.getUsername());
		if (!(updateUser.getPassword().equals(verificablePss))) {
			updateUser.setPassword(verificablePss);
		}
		userDAO.saveOrUpdateUser(updateUser);
	}

}
